﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Net;
using System.IO;
using Rensselaer_Event_Finder.Hibernate;
using Rensselaer_Event_Finder.Hibernate.DAO;
using Rensselaer_Event_Finder.com.bluetechinc.redandwhite;

namespace Rensselaer_Event_Finder
{
    /**
     * Singleton class that stores many objects and variables needed
     * throughout the application
     **/
    public static class Globals
    {

        #region Variables

        private static UserDAO userDAO;
        private static EventDAO eventDAO;
        private static LocationDAO locationDAO;
        private static EventCommentDAO eventCommentDAO;
        private static LocationCommentDAO locationCommentDAO;
        private static LocationRatingDAO locationRatingDAO;
        private static CategoryDAO categoryDAO;
        private static SyncDAO syncDAO;
        private static database webServices;
        private static User currentUser;
        private static DateTime lastUpdated;
        private static bool up = false;
        
        #endregion

        #region Public Methods

        public static UserDAO getUserService()
        {
            if (userDAO == null) userDAO = new UserDAO();
            return userDAO;
        }
        public static EventDAO getEventService()
        {
            if (eventDAO == null) eventDAO = new EventDAO();
            return eventDAO;
        }
        public static LocationDAO getLocationService()
        {
            if (locationDAO == null) locationDAO = new LocationDAO();
            return locationDAO;
        }
        public static EventCommentDAO getEventCommentService()
        {
            if (eventCommentDAO == null) eventCommentDAO = new EventCommentDAO();
            return eventCommentDAO;
        }
        public static LocationCommentDAO getLocationCommentService()
        {
            if (locationCommentDAO == null) locationCommentDAO = new LocationCommentDAO();
            return locationCommentDAO;
        }
        public static LocationRatingDAO getLocationRatingService()
        {
            if (locationRatingDAO == null) locationRatingDAO = new LocationRatingDAO();
            return locationRatingDAO;
        }
        public static CategoryDAO getCategoryService()
        {
            if (categoryDAO == null) categoryDAO = new CategoryDAO();
            return categoryDAO;
        }
        public static SyncDAO getSyncService()
        {
            if (syncDAO == null) syncDAO = new SyncDAO();
            return syncDAO;
        }

        public static database getWebService()
        {
            if (webServices == null) webServices = new database();
            return webServices;
        }

        public static User CurrentUser
        {
            get
            {
                return currentUser;
            }
            set
            {
                currentUser = value;
            }
        }

        /// <summary>
        /// Averages all of the ratings for a location and returns a round integer value
        /// </summary>
        /// <param name="loc">Location to get ratings for</param>
        /// <returns></returns>
        public static int getIntAverageRating(Location loc)
        {
            if (loc.Ratings.Count > 0)
            {
                int sum = 0;
                for (int i = 0; i < loc.Ratings.Count; i++)
                {
                    sum += loc.Ratings[i].Rating;
                }
                int average = Convert.ToInt32(((double)sum / (double)loc.Ratings.Count));
                return average;
            }
            else
                return 0;
        }

        /// <summary>
        /// Averages all of the ratings for a location and returns the value as a double
        /// </summary>
        /// <param name="loc">Location to get ratings for</param>
        /// <returns></returns>
        public static double getDoubleAverageRating(Location loc)
        {
            if (loc.Ratings.Count > 0)
            {
                int sum = 0;
                for (int i = 0; i < loc.Ratings.Count; i++)
                {
                    sum += loc.Ratings[i].Rating;
                }
                double average = ((double)sum / (double)loc.Ratings.Count);
                return average;
            }
            else
                return 0;
        }

        /// <summary>
        /// Loads the image from the web server url that is given
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static Bitmap loadImageFromURL(string url)
        {
            HttpWebRequest wreq;
            HttpWebResponse wresp;
            Stream mystream;
            Bitmap bmp;

            bmp = null;
            mystream = null;
            wresp = null;
            try
            {
                if (url == null || url == "")
                {
                    return Properties.Resources.no_image_available;
                }
                if (!url.StartsWith("blog"))
                {
                    if (!url.StartsWith("www.") && !url.StartsWith("http"))
                    {
                        url = "www." + url;
                    }
                }
                if (!url.StartsWith("http"))
                {
                    url = "http://" + url;
                }
                url = url.Replace(" ", "%20");
                wreq = (HttpWebRequest)WebRequest.Create(url);
                wreq.AllowWriteStreamBuffering = true;

                wresp = (HttpWebResponse)wreq.GetResponse();

                if ((mystream = wresp.GetResponseStream()) != null)
                    bmp = new Bitmap(mystream);
            }
            finally
            {
                if (mystream != null)
                    mystream.Close();

                if (wresp != null)
                    wresp.Close();
            }

            return (bmp);
        }

        public static void syncDatabase(System.Windows.Forms.ToolStripProgressBar progressBar)
        {
            Sync lastUpdate = getSyncService().getById(1);
            if (!up)
            {
                lastUpdated = lastUpdate.UpdatedTime;
                up = true;
            }
            String inserts = getWebService().sync(lastUpdated);

            String[] splits = inserts.Split('\n');
            int i = 0;
            progressBar.Maximum = splits.Length;
            foreach (String s in splits)
            {
                progressBar.Increment(1);
                if (s.Length > 0)
                {
                    Globals.getCategoryService().executeSQL(s);
                }
                if (i == splits.Length - 1)
                {
                    String newtime = s.Substring(s.IndexOf('\'') + 1, s.Length - s.IndexOf('\'') - 2);
                    int year = Convert.ToInt32(newtime.Split('-')[0]);
                    int month = Convert.ToInt32(newtime.Split('-')[1]);
                    int day = Convert.ToInt32(newtime.Split('-')[2].Split(' ')[0]);
                    int hour = Convert.ToInt32(newtime.Split(' ')[1].Split(':')[0]);
                    int min = Convert.ToInt32(newtime.Split(' ')[1].Split(':')[1]);
                    int sec = Convert.ToInt32(newtime.Split(' ')[1].Split(':')[2]);
                    lastUpdated = new DateTime(year, month, day, hour, min, sec);
                }
                i++;
            }
        }
        public static void syncDatabase()
        {
            Sync lastUpdate = getSyncService().getById(1);
            if (!up)
            {
                lastUpdated = lastUpdate.UpdatedTime;
                up = true;
            }
            String inserts = getWebService().sync(lastUpdated);
            String t = convertDateTime(lastUpdated);
            String[] splits = inserts.Split('\n');
            int i = 0;
            foreach (String s in splits)
            {
                if (s.Length > 0)
                {
                    Globals.getCategoryService().executeSQL(s);
                }
                if (i == splits.Length-1)
                {
                    String newtime = s.Substring(s.IndexOf('\'')+1, s.Length - s.IndexOf('\'')-2);
                    int year = Convert.ToInt32(newtime.Split('-')[0]);
                    int month = Convert.ToInt32(newtime.Split('-')[1]);
                    int day = Convert.ToInt32(newtime.Split('-')[2].Split(' ')[0]);
                    int hour = Convert.ToInt32(newtime.Split(' ')[1].Split(':')[0]);
                    int min = Convert.ToInt32(newtime.Split(' ')[1].Split(':')[1]);
                    int sec = Convert.ToInt32(newtime.Split(' ')[1].Split(':')[2]);
                    lastUpdated = new DateTime(year,month,day,hour,min,sec);
                }
                i++;
            }
        }

        public static String sanitizeSQL(String s)
        {
            return(s.Replace("'", "\'"));

        }
        
        private static String convertDateTime(DateTime t)
        {
            String result = "";
            result += t.Year.ToString() + "-";
            result += t.Month.ToString() + "-";
            result += t.Day.ToString() + " ";
            result += t.Hour.ToString() + ":";
            result += t.Minute.ToString() + ":";
            result += t.Second.ToString();
            return result;
        }

        #endregion

    }
}
